package com.mcglib.flac
{
	
	import flash.display.DisplayObjectContainer;
	import flash.display.InteractiveObject;
	import flash.events.FocusEvent;
	import flash.events.MouseEvent;
	import flash.events.TextEvent;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.utils.clearTimeout;
	import flash.utils.setTimeout;
	
	[Event(name="valueChange",type="com.mcglib.flac.FlacEvent")]
	public class NumericStepper extends FlacComponent
	{	
		private var btnPrev:InteractiveObject;
		
		private var btnNext:InteractiveObject;
		
		private var numText:TextField;
		
		private var btnMin:InteractiveObject;
		
		private var btnMax:InteractiveObject;
		
		private var _value:Number = 0;
		
		private var _maxValue:Number = 100;
		
		private var _minValue:Number = 0;
		
		private var _stepSize:Number = 1;
		
		private var _viewFormatFun:Function;
		
		private var _textEditable:Boolean;
		
		private var _autoIncrease:Boolean = true;
		
		public function NumericStepper(numText:TextField,btnPrev:InteractiveObject,btnNext:InteractiveObject,
									   viewFormatFun:Function=null,btnMin:InteractiveObject=null,btnMax:InteractiveObject=null)
		{
			super();
			
			this.numText = numText;
			this.btnPrev = btnPrev;
			this.btnNext = btnNext;
			this.btnMin = btnMin;
			this.btnMax = btnMax;
			_viewFormatFun = viewFormatFun;
			
			
			
			btnPrev.addEventListener(MouseEvent.MOUSE_DOWN,onBtnPrevMouseDown);
			btnNext.addEventListener(MouseEvent.MOUSE_DOWN,onBtnNextMouseDown);
			btnPrev.addEventListener(MouseEvent.MOUSE_UP,onBtnMouseUp);
			btnNext.addEventListener(MouseEvent.MOUSE_UP,onBtnMouseUp);
			
			
			
			btnMin && btnMin.addEventListener(MouseEvent.CLICK,onBtnMinClick);
			btnMax && btnMax.addEventListener(MouseEvent.CLICK,onBtnMaxClick);
			
			
			textEditable = true;
			updateValue(minValue,false);
		}
		
		public static function createByAsset(asset:DisplayObjectContainer,viewFormatFun:Function=null):NumericStepper{
			var tf:TextField = asset.getChildByName("tf") as TextField;
			if(tf==null)
				throw "资源内部缺少命名为tf的textField";
			
			var btnPrev:InteractiveObject = asset.getChildByName("btnPrev")  as InteractiveObject;
			if(btnPrev==null)
				throw "资源内部缺少命名为btnPrev的InteractiveObject";
		
			var btnNext:InteractiveObject = asset.getChildByName("btnNext")  as InteractiveObject;
			if(btnNext==null)
				throw "资源内部缺少命名为btnNext的InteractiveObject";
			
			
			var btnMin:InteractiveObject = asset.getChildByName("btnMin") as InteractiveObject;
			var btnMax:InteractiveObject = asset.getChildByName("btnMax") as InteractiveObject;
			
			return new NumericStepper(tf,btnPrev,btnNext,viewFormatFun,btnMin,btnMax);
		}
		
		public function get autoIncrease():Boolean
		{
			return _autoIncrease;
		}
		
		public function set autoIncrease(value:Boolean):void
		{
			_autoIncrease = value;
		}
		
		public function get textEditable():Boolean
		{
			return _textEditable;
		}
		
		public function set textEditable(value:Boolean):void
		{
			_textEditable = value;
			if(value){
				numText.addEventListener(TextEvent.TEXT_INPUT,onTextInput);
				numText.addEventListener(FocusEvent.FOCUS_IN,onTextFocusIn);
				numText.addEventListener(FocusEvent.FOCUS_OUT,onTextFocusOut);
				numText.addEventListener(FocusEvent.MOUSE_FOCUS_CHANGE,onTextFocusOut);
				
				numText.type = TextFieldType.INPUT;
				numText.selectable = true;
			}else{
				numText.removeEventListener(TextEvent.TEXT_INPUT,onTextInput);
				numText.removeEventListener(FocusEvent.FOCUS_IN,onTextFocusIn);
				numText.removeEventListener(FocusEvent.FOCUS_OUT,onTextFocusOut);
				numText.removeEventListener(FocusEvent.MOUSE_FOCUS_CHANGE,onTextFocusOut);
			
				numText.type = TextFieldType.DYNAMIC;
				numText.selectable = false;
			}
		}
		
		public function get stepSize():Number
		{
			return _stepSize;
		}
		
		public function set stepSize(value:Number):void
		{
			_stepSize = value;
		}
		
		public function get minValue():Number
		{
			return _minValue;
		}
		
		public function set minValue(value:Number):void
		{
			
			if(value>_maxValue)
				throw new Error("minValue应该<=maxValue");
			
			_minValue = value;
			
			if(_value<_minValue){
				updateValue(_minValue);
			}
		}
		
		public function get maxValue():Number
		{
			return _maxValue;
		}
		
		public function set maxValue(value:Number):void
		{
			if(value<_minValue)
				throw new Error("maxValue应该>=minValue");
			
			
			_maxValue = value;
			
			if(_value>maxValue){
				updateValue(_maxValue);
			}
		}
		
		public function get value():Number
		{
			if(_value<_minValue){
				updateValue(_minValue);
			}else if(_value>_maxValue){
				updateValue(_maxValue);
			}
			
			return _value;
		}
		
		public function set value(value:Number):void
		{
			if(_value==value)
				return;
			
			if(value>maxValue)
				value = maxValue;
			else if(value<minValue)
				value = minValue;
			
			updateValue(value);
		}
		
		private var mdHandler:int;
		private var mdJs:int=1;
		private function onBtnPrevMouseDown(e:MouseEvent):void{
			
			clearTimeout(mdHandler);
			while(mdJs>0){
				var abs:int = _stepSize*mdJs;
				if((_value-abs)>=_minValue){
					updateValue(_value-abs);
					break;
				}else{
					mdJs--;
				}
			}
			mdJs++;
			if(_autoIncrease && _value>_minValue)
				mdHandler = setTimeout(onBtnPrevMouseDown,100,null);
		}
		
		private function onBtnNextMouseDown(e:MouseEvent):void{
			clearTimeout(mdHandler);
			
			while(mdJs>0){
				var abs:int = _stepSize*mdJs;
				if((_value+abs)<=_maxValue){
					updateValue(_value+abs);
					break;
				}else{
					mdJs--;
				}
			}
			mdJs++;
			if(_autoIncrease && _value<_maxValue)
				mdHandler = setTimeout(onBtnNextMouseDown,100,null);
		}
		
		private function onBtnMouseUp(e:MouseEvent):void{
			mdJs=1;
			clearTimeout(mdHandler);
		}
		
		private function onTextInput(e:TextEvent):void{
			var n:Number = Number(e.text);
			if(!isNaN(n)){
				
			}else{
				e.preventDefault();
			}
		}
		
		private function onTextFocusIn(e:FocusEvent):void{
			numText.htmlText = value+"";
		}
		
		private function onTextFocusOut(e:FocusEvent):void{
			var n:Number = Number(numText.text);
			if(isNaN(n))
				return;
			
			if(n>_maxValue){
				n = _maxValue;
			}else if(n<_minValue){
				n = _minValue;
			}
			
			
			updateValue(n,_value!=n);
			
		}
		
		private function onBtnMinClick(e:MouseEvent):void{
			updateValue(minValue);
		}
		
		private function onBtnMaxClick(e:MouseEvent):void{
			updateValue(maxValue);
		}
		
		private function updateValue(v:Number,dispatchEvt:Boolean=true):void{
			_value = v;
			if(_viewFormatFun==null){
				numText.htmlText = _value+"";
			}else{
				numText.htmlText = _viewFormatFun(_value,_minValue,_maxValue);
			}
			
			if(_value==minValue){
				btnPrev.mouseEnabled = false;
				if(btnMin)
					btnMin.mouseEnabled = false;
				FlacUtils.gray(btnPrev);
				btnMin &&  FlacUtils.gray(btnMin);
			}else{
				FlacUtils.cancelGray(btnPrev);
				btnMin &&  FlacUtils.cancelGray(btnMin);
				btnPrev.mouseEnabled = true;
				if(btnMin)
					btnMin.mouseEnabled = true;
			}
			
			if(_value==maxValue){
				FlacUtils.gray(btnNext);
				btnMin &&  FlacUtils.gray(btnMax);
				btnNext.mouseEnabled = false;
				if(btnMax)
					btnMax.mouseEnabled = false;
			}else{
				FlacUtils.cancelGray(btnNext);
				btnMin &&  FlacUtils.cancelGray(btnMax);
				btnNext.mouseEnabled = true;
				if(btnMax)
					btnMax.mouseEnabled = true;
			}
			
			if(dispatchEvt){
				var e:FlacEvent = new FlacEvent(FlacEvent.VALUE_CHANGE);
				e.value = _value;
				
				dispatchEvent(e);
			}
		}
		
		

	}
}